package media

import (
	"gitee.com/yangzx6606/core/conn/client"
	"gitee.com/yangzx6606/core/pb"
	log "github.com/golang/glog"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/types/known/anypb"
)

type Pusher struct {
	client   client.Client
	parser   pb.MessagePacketParser
	isPushed bool
}

func NewPusher(c client.Client) *Pusher {
	p := &Pusher{client: c}
	p.client.AttachObserver(p, p)
	return p
}

func (p *Pusher) Open() error {
	return p.client.Open()
}

func (p *Pusher) Close() {
	p.client.Close()
}

// OnData 连接服务器收到数据
func (p *Pusher) OnData(packet *client.Packet, args any) {
	if packet.Type == client.PacketTypeData {
		// 组帧及帧反序列化
		p.parser.PushData(packet.Data, p.onPacket)
	} else if packet.Type == client.PacketTypeConnected {
		log.Info("连接媒体服务器成功")
	} else if packet.Type == client.PacketTypeConnectLost {
		log.Warning("媒体服务器连接断开")
	}
}

// 解帧后的数据包
func (p *Pusher) onPacket(_ []byte, packet *pb.Packet) {
	if packet.Type == pb.PacketType_Cmd {
		cmd := pb.CmdPullRequest{}
		err := anypb.UnmarshalTo(packet.Data, &cmd, proto.UnmarshalOptions{})
		if err != nil {
			log.Error("解码Any失败：", err)
			return
		}
		if cmd.Cmd == pb.CmdType_CmdPullStart {
			p.isPushed = true
		} else if cmd.Cmd == pb.CmdType_CmdPullStop {
			p.isPushed = false
		}
	}
}

func (p *Pusher) OnVideoData(pkt *VideoPacket) {
	if pkt.Type == VideoPacketTypeFrame || pkt.Type == VideoPacketTypeKeyFrame || pkt.Type == VideoPacketTypeCodec {
		p.pushMedia(pkt)
	} else if pkt.Type == VideoPacketTypeConnected {
		log.Info("视频设备连接成功")
	} else if pkt.Type == VideoPacketTypeConnectLost {
		log.Error("视频设备连接断开")
	}
}

func (p *Pusher) pushMedia(pkt *VideoPacket) {
	if !p.isPushed {
		return
	}
	data, err := proto.Marshal(pkt.Packet)
	if err != nil {
		log.Error("序列化媒体数据失败：", err)
		return
	}
	packet := &client.Packet{Type: client.PacketTypeData, Data: data}
	err = p.client.Write(packet)
	if err != nil {
		log.Error("写入数据帧失败：", err)
	}
}
